﻿#Region " DirectoryObjectクラス "
''' <summary>
''' Directory オブジェクトを表す抽象基本クラスです。
''' </summary>
''' <remarks></remarks>
Public MustInherit Class DirectoryObject
  Implements IDirectory

#Region " プライベートフィールド "
  Private ReadOnly _entry As DirectoryEntry
  Private ReadOnly _category As CategoryType
  Private ReadOnly _name As String
  Private _disposed As Boolean
#End Region

#Region " プロテクトコンストラクター "
  ''' <summary>
  ''' <see cref="DirectoryEntry"/> を指定して <see cref="DirectoryObject"/> クラスの新しいインスタンスを初期化します。
  ''' </summary>
  ''' <param name="entry"><see cref="DirectoryEntry"/>。</param>
  ''' <exception cref="ArgumentNullException"><paramref name="entry"/> が Nothing です。</exception>
  ''' <exception cref="ArgumentException"><paramref name="entry"/> の種類が <see cref="CategoryType"/> に該当しません。</exception>
  ''' <remarks></remarks>
  Protected Sub New(entry As DirectoryEntry)
    If entry Is Nothing Then
      Throw New ArgumentNullException("entry", "entry が Nothing です。")
    End If
    If [Enum].TryParse(Of CategoryType)(entry.SchemaClassName, True, _category) = False Then
      Throw New ArgumentException("entry の種類が CategoryType に該当しません。", "entry")
    End If

    _entry = entry
    _name = _entry.Name
  End Sub
#End Region

#Region " パブリックプロパティ "
  ''' <summary>
  ''' Directory オブジェクトの種類を取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>Directory オブジェクトの種類。</returns>
  ''' <remarks></remarks>
  Public ReadOnly Property Category As CategoryType
    Get
      Return _category
    End Get
  End Property

  ''' <summary>
  ''' 説明を取得または設定します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>説明。</returns>
  ''' <remarks></remarks>
  Public Property Description As String Implements IDirectory.Description
    Get
      If _disposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return DirectCast(_entry.Properties.Item("description").Value, String)
    End Get
    Set(value As String)
      If _disposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      _entry.Properties.Item("description").Value = value
    End Set
  End Property

  ''' <summary>
  ''' 関連付けられた <see cref="DirectoryEntry"/> を取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>関連付けられた <see cref="DirectoryEntry"/>。</returns>
  ''' <remarks></remarks>
  Public ReadOnly Property Entry As DirectoryEntry Implements IDirectory.Entry
    Get
      If _disposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return _entry
    End Get
  End Property

  ''' <summary>
  ''' オブジェクトが破棄されているかどうかを取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>オブジェクトが破棄されている場合は true。それ以外の場合は false。</returns>
  ''' <remarks></remarks>
  Public ReadOnly Property IsDisposed As Boolean Implements IDirectory.IsDisposed
    Get
      Return _disposed
    End Get
  End Property

  ''' <summary>
  ''' 名前を取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>名前。</returns>
  ''' <remarks></remarks>
  Public Overridable ReadOnly Property Name As String Implements IDirectory.Name
    Get
      Return _name
    End Get
  End Property
#End Region

#Region " パブリックメソッド "
  ''' <summary>
  ''' 使用されているリソースを解放します。
  ''' </summary>
  ''' <remarks></remarks>
  Public Sub Dispose() Implements IDisposable.Dispose
    Me.Dispose(True)
    GC.SuppressFinalize(Me)
  End Sub

  ''' <summary>
  ''' 名前を返します。
  ''' </summary>
  ''' <returns>名前。</returns>
  ''' <remarks></remarks>
  Public Overrides Function ToString() As String
    Return Me.Name
  End Function
#End Region

#Region " プロテクトメソッド "
  ''' <summary>
  ''' 使用されているリソースを解放し、オプションでマネージ リソースも解放します。
  ''' </summary>
  ''' <param name="disposing">マネージ リソースとアンマネージ リソースの両方を解放する場合は true。
  ''' アンマネージ リソースだけを解放する場合は false。</param>
  ''' <remarks></remarks>
  Protected Overridable Sub Dispose(disposing As Boolean)
    If _disposed = False Then
      If disposing Then
        _entry.Close()
      End If
      _disposed = True
    End If
  End Sub
#End Region
End Class
#End Region

#Region " DomainObjectクラス "
''' <summary>
''' ドメインの Directory オブジェクトを表す抽象基本クラスです。
''' </summary>
''' <remarks></remarks>
Public MustInherit Class DomainObject
  Inherits DirectoryObject
  Implements IDomain

#Region " プライベートフィールド "
  Private ReadOnly _path, _name As String
#End Region

#Region " プロテクトコンストラクター "
  ''' <summary>
  ''' <see cref="DirectoryEntry"/> を指定して <see cref="DomainObject"/> クラスの新しいインスタンスを初期化します。
  ''' </summary>
  ''' <param name="entry"><see cref="DirectoryEntry"/>。</param>
  ''' <exception cref="ArgumentNullException"><paramref name="entry"/> が Nothing です。</exception>
  ''' <exception cref="ArgumentException"><paramref name="entry"/> の種類が <see cref="CategoryType"/> に該当しません。</exception>
  ''' <remarks></remarks>
  Protected Sub New(entry As DirectoryEntry)
    MyBase.New(entry)
    _path = DirectoryAccess.GetBelongPath(entry)
    _name = entry.Properties.Item("name").Value.ToString()
  End Sub
#End Region

#Region " パブリックプロパティ "
  ''' <summary>
  ''' 表示用の所属パスを取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>表示用の所属パス。</returns>
  ''' <remarks></remarks>
  Public ReadOnly Property DisplayPath As String Implements IDomain.DisplayPath
    Get
      Return _path
    End Get
  End Property

  ''' <summary>
  ''' 表示用の名前を取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>表示用の名前。</returns>
  ''' <remarks></remarks>
  Public Overrides ReadOnly Property Name As String
    Get
      Return _name
    End Get
  End Property
#End Region
End Class
#End Region
